'''
# Coding:utf-8
# Project: iiop
# Author: rtf
# Time: 2021-04-16 14:20:13
# FileName: dynamic_word.py
# Software: PyCharm
'''

import base64
import docx
import bs4
import datetime
from docx.shared import Pt, Cm, Inches
from docx.oxml.ns import qn
from bs4 import BeautifulSoup
from func.root_path import get_path

html_content = '''
<p><span style="color: #2dc26b;">手动<strong>阀手动阀<span style="font-family: 'arial black', sans-serif;">士大夫大师傅的方式<span style="font-size: 24pt;">打<span style="background-color: #e03e2d;">发士大夫</span></span></span></strong></span></p>
<p><span style="color: #2dc26b;">s'd发士大夫</span></p>
<table style="border-collapse: collapse; width: 100%; height: 112px;" border="1">
<tbody>
<tr style="height: 14px;">
<td style="height: 70px; width: 19.3943%;" rowspan="5">犯得上地方</td>
<td style="height: 14px; width: 38.7886%;" colspan="2" rowspan="3">哈哈哈</td>
<td style="width: 19.4484%; height: 14px;">0,3</td>
<td style="width: 19.4484%; height: 14px;">0,4</td>
</tr>
<tr style="height: 14px;">
<td style="width: 19.4484%; height: 14px;">1,3</td>
<td style="width: 19.4484%; height: 14px;">1,4</td>
</tr>
<tr style="height: 14px;">
<td style="width: 19.4484%; height: 14px;">2,3</td>
<td style="width: 19.4484%; height: 14px;">2,4</td>
</tr>
<tr style="height: 14px;">
<td style="width: 19.3943%; height: 14px;">3,1</td>
<td style="width: 19.3943%; height: 14px;">3,2</td>
<td style="width: 19.4484%; height: 14px;">3,3</td>
<td style="width: 19.4484%; height: 14px;">3,4</td>
</tr>
<tr style="height: 14px;">
<td style="width: 19.3943%; height: 14px;">4,1</td>
<td style="width: 19.3943%; height: 14px;">4,2</td>
<td style="width: 19.4484%; height: 14px;">4,3</td>
<td style="width: 19.4484%; height: 14px;">4,4</td>
</tr>
<tr style="height: 14px;">
<td style="width: 19.3943%; height: 14px;">5,0</td>
<td style="width: 19.3943%; height: 14px;">5,1</td>
<td style="width: 19.3943%; height: 14px;">5,2</td>
<td style="width: 19.4484%; height: 14px;">5,3</td>
<td style="width: 19.4484%; height: 14px;">5,4</td>
</tr>
<tr style="height: 14px;">
<td style="width: 19.3943%; height: 14px;">6,0</td>
<td style="width: 19.3943%; height: 14px;">6,1</td>
<td style="width: 19.4484%; height: 14px;" colspan="2">6,2 6,3 merge</td>
<td style="width: 19.4484%; height: 14px;">6,4</td>
</tr>
<tr style="height: 14px;">
<td style="width: 19.3943%; height: 14px;">7,0</td>
<td style="width: 19.3943%; height: 14px;">7,1</td>
<td style="width: 19.3943%; height: 14px;">7,2</td>
<td style="width: 19.3943%; height: 14px;"; colspan="2">7,3 7,4 merge</td>
</tr>
</tbody>
</table>
<p><img src="" alt="" width="482" height="484" /></p>
'''

html_content1 = '''
<table style="border-collapse: collapse; width: 100%; height: 98px;" border="1">
<tbody>
<tr style="height: 14px;">
<td style="width: 18.3304%; height: 56px;" colspan="2" rowspan="4">横向</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
</tr>
<tr style="height: 14px;">
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
</tr>
<tr style="height: 14px;">
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 56px;" rowspan="4">纵向</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="height: 14px; width: 18.3304%;" colspan="2" rowspan="2">横向</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
</tr>
<tr style="height: 14px;">
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
</tr>
<tr style="height: 14px;">
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
</tr>
<tr style="height: 14px;">
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="height: 14px; width: 36.6607%;" colspan="4">横向</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
</tr>
<tr style="height: 14px;">
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
<td style="width: 9.16518%; height: 14px;">1</td>
</tr>
</tbody>
</table>
'''

IMAGE_MIME_TYPE = {"image/gif": "gif",
                   "image/png": "png",
                   "image/jpeg": "jpg",
                   "image/svg+xml": "svg"}


def save_image(img_str, image_name):
    mime_type = img_str[img_str.find(":") + 1:img_str.find(";")]
    img_str = img_str[len(mime_type) + 13:]
    img_data = base64.b64decode(img_str)
    filename = f'{get_path()}/images/{image_name}.{IMAGE_MIME_TYPE.get(mime_type)}'
    with open(filename, 'wb') as f:
        f.write(img_data)
        f.close()
    return filename


def dynamic_process(html_content, position_text, docx_path):
    doc = docx.Document(docx_path)
    paragraph = None
    for i, p in enumerate(doc.paragraphs):  # 遍历所有的段落
        if position_text in p.text:
            paragraph = doc.paragraphs[i]
            p.add_run("\n")
            break
    soup = BeautifulSoup(html_content, 'html.parser')
    soup.prettify()
    for i in range(0, len(soup.contents)):
        if isinstance(soup.contents[i], bs4.element.Tag):
            p_style = str_to_json(soup.contents[i].attrs.get("style"))
            text = str()
            if not isinstance(soup.contents[i].span, int) and soup.contents[i].span:  # 文本
                for child in soup.contents[i].descendants:
                    if isinstance(child, bs4.element.NavigableString) and child:
                        text += child
                    else:
                        style = str_to_json(child.attrs.get("style"))
                run = paragraph.add_run(text)
                if style:
                    if style.get("font-size"):
                        run.font.size = Pt(int(float(style.get("font-size")[:-2])))
                    run.font.name = style.get("font-family")
                    r = run._element
                    if r.rPr.rFonts:
                        r.rPr.rFonts.set(qn('w:eastAsia'), style.get("font-family"))
                    if p_style:
                        # 首行缩进
                        if p_style.get("text-indent"):
                            r.rPr.first_line_indent = Pt(int(float(p_style.get("text-indent")[:-2])))
                            # paragraph.paragraph_format.first_line_indent = Pt(int(float(p_style.get("text-indent")[:-2])))
                        if p_style.get("line-height"):
                            paragraph.paragraph_format.line_spacing = Pt(int(float(p_style.get("line-height")[:-2])))
            elif not isinstance(soup.contents[i].tbody, int) and soup.contents[i].tbody:  # 表格
                cols = 0
                for child in soup.contents[i].tbody.children:
                    temp_cols = str(child).count("</td>")
                    if temp_cols > cols:
                        cols = temp_cols
                rows = str(soup.contents[i].tbody).count("</tr>")
                table = doc.add_table(rows=rows, cols=cols, style='Table Grid')  # 添加一个空表
                move_table_after(table, paragraph)
                str_line = 0
                merge_list = list()
                for row in range(0, len(soup.contents[i].tbody.contents)):
                    soup_row = soup.contents[i].tbody.contents[row]
                    temp_cols = str(soup_row).count("</td>")
                    if isinstance(soup_row, bs4.element.Tag):
                        newline = 0
                        for col in range(0, len(soup_row.contents)):
                            soup_col = soup_row.contents[col]
                            if soup_col != "\n":
                                newline += 1

                            # 实际列位置 = 原始位置 - 换行
                            # 实际行位置 = 原始位置 - 空行
                            real_col = col - newline
                            real_row = row - str_line
                            if isinstance(soup_col, bs4.element.Tag):
                                attrs = soup_col.attrs
                                colspan = int(attrs.get("colspan")) if attrs.get("colspan") else None
                                rowspan = int(attrs.get("rowspan")) if attrs.get("rowspan") else None
                                if colspan and rowspan:
                                    # print(soup.contents[i].tbody)
                                    # merge_rowspan = int(rowspan) - 1
                                    # table.cell(real_row, real_col).merge(table.cell(real_row + merge_rowspan, real_col))
                                    # table.cell(real_row, real_col).text = soup_col.text
                                    # print("=======", real_row, real_col, real_row + merge_rowspan, real_col)
                                    # merge_colspan = int(colspan) - 1
                                    #
                                    # print("====merge_colspan===", real_row, real_col, merge_rowspan, real_col + merge_colspan)
                                    # table.cell(real_row, real_col).merge(table.cell(merge_rowspan, real_col + merge_colspan))
                                    # table.cell(real_row, real_col).text = soup_col.text
                                    # print("=======", real_row, real_col, merge_rowspan, real_col + merge_colspan)
                                    for r in range(real_row, rowspan):
                                        for c in range(1, colspan):
                                            table.cell(r, real_col).merge(table.cell(r, real_col+1))
                                            table.cell(real_row, real_col).text = soup_col.text

                                    for r in range(real_row, rowspan):
                                        for c in range(real_col, real_col + colspan):
                                            merge_list.append((r, c))
                                elif rowspan:
                                    merge_rowspan = int(rowspan) - 1
                                    table.cell(real_row, real_col).merge(table.cell(real_row + merge_rowspan, real_col))
                                    table.cell(real_row, real_col).text = soup_col.text
                                    for r in range(real_row, real_row + rowspan):
                                        merge_list.append((r, real_col))
                                elif colspan:
                                    merge_colspan = int(colspan) - 1
                                    table.cell(real_row, real_col).merge(table.cell(real_row, real_col + merge_colspan))
                                    table.cell(real_row, real_col).text = soup_col.text
                                    for c in range(real_col, real_col + colspan):
                                        merge_list.append((real_row, c))
                                else:  # 单元格赋值
                                    if temp_cols < cols:  # 是否有合并单元格
                                        whether_shift = False
                                        for m in merge_list:
                                            if m[0] == real_row and m[1] == 0:  # 首列合并
                                                whether_shift = True
                                            elif m[0] == real_row and m[1] < real_col:  # 当前列之前合并
                                                whether_shift = True
                                        if whether_shift:  # 首列合并、当前列之前合并，赋值单元格位置 +1
                                            new_col = real_col + (cols - temp_cols)
                                        else:
                                            new_col = real_col
                                    else:
                                        new_col = real_col
                                    table.cell(real_row, new_col).text = soup_col.text
                    else:
                        str_line += 1
            elif not isinstance(soup.contents[i].img, int) and soup.contents[i].img:  # 图片

                image_info = soup.contents[i].img.attrs
                # width = image_info.get("width") if image_info.get("width") else 5
                # height = image_info.get("height") if image_info.get("height") else 5
                img_str = image_info.get("src")

                image_path = save_image(img_str, datetime.datetime.now().strftime('%Y%m%d%H%M%S%f'))
                run = paragraph
                paragraph.add_run("\n")
                run.runs[0].add_picture(image_path, width=Inches(5))
                paragraph.add_run("\n")
            else:
                pass

    doc.save(docx_path)


def str_to_json(styles):
    if styles:
        styles = styles.split(";")
        style = dict()
        for s in styles:
            s = s.split(":")
            if len(s) > 1:
                style[s[0].strip()] = s[1].strip()
        return style
    else:
        None


def move_table_after(table, paragraph):
    tbl, p = table._tbl, paragraph._p
    p.addnext(tbl)


def delete_paragraph(paragraph):
    p = paragraph._element
    p.getparent().remove(p)
    p._p = p._element = None

# dynamic_process(html_content, "1.2 主要依据", "../download/doc/NON_PURCHASE_tpl1.docx")

# doc = docx.Document("../download/doc/NON_PURCHASE_tpl1.docx")
# for i, p in enumerate(doc.paragraphs):  # 遍历所有的段落
#     print(i, p.text)
#     if '1.1 基本情况' in p.text:
#         doc.paragraphs[i - 1].runs[-1].add_break()
#         doc.paragraphs[i-1].runs[0].add_text("$$$$$$$$$$$$$$$$$$")
#     #     p.runs[-1].add_break()
#     #     p.runs[-1].add_text("##################")
#         # p.runs[-1].add_picture(photo_dit_path)  # 在runs的最后一段文字后添加图片


# from docx import Document
# from docx.shared import Pt
# from docx.shared import Inches
# from docx.oxml.ns import qn
#
# doc = Document()
# doc.add_heading('项目可行性研究报告', 1)
# doc.add_paragraph("项目名称：XXXXX")
# doc.add_paragraph("项目申报单位：XXXXX")
# doc.save("../download/doc/test.docx")